package routers

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"shqsoft.cn/pasnj/base"
	"strconv"
	"strings"
	"time"

	"github.com/labstack/echo"
)

func UploadRouter(c echo.Context) error {
	name := c.Param("Name")
	if name == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "Name不能为空！")
	}
	file, err := c.FormFile(name)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	src, err := file.Open()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	defer src.Close()
	ip := getIpAttr(c.Request())
	ip = strings.Replace(ip, ".", "", -1)
	ip = strings.Replace(ip, ":", "", 1)
	fileName := name + ip + time.Now().Format("20060102-150405") + "." + base.GetExtenName(file.Filename)
	path, err := base.WorkDir()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	path = path + "/upload_file/" + fileName
	dst, err := os.Create(path)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	defer dst.Close()
	if _, err = io.Copy(dst, src); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	dataImport := &base.DataImport{
		FilePath: path,
	}
	dataImport.InitReader()
	sheetNames, err := dataImport.GetSheetNames()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	dMap, err := base.GetDataMap(name)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	return c.HTML(http.StatusOK, getSuccessMessage(fileName, sheetNames, dMap))
}
func UploadDeleteRouter(c echo.Context) error {
	fileName := c.Param("FileName")
	if fileName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "FileName不能为空！")
	}
	path, err := base.WorkDir()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	filePath := path + "/upload_file/" + fileName
	err = os.Remove(filePath)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.HTML(http.StatusOK, `{"success":true}`)
}
func DataMapRouter(c echo.Context) error {
	var dataImport base.DataImport
	jsonStr := c.FormValue("dataImport")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &dataImport)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	} else {
		return echo.NewHTTPError(http.StatusBadRequest, "FormValue：dataImport不能为空！")
	}
	path, err := base.WorkDir()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, getErrorMessage(err.Error()))
	}
	dataImport.FilePath = path + "/upload_file/" + dataImport.FilePath
	err = dataImport.InitReader()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	dataMap, _ := dataImport.GetDataMap()
	dataColumns, err := dataImport.GetDataColumns()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	isOk := checkFileColumns(dataColumns, dataMap)
	dmBytes, err := json.Marshal(&dataMap)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	dcBytes, err := json.Marshal(&dataColumns)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.HTML(http.StatusOK, fmt.Sprintf(`{"dataMaps":%s,"columns":%s,"success":%t}`, string(dmBytes), string(dcBytes), isOk))
}

//CheckFileColumns 检查导入文件的数据列
func checkFileColumns(columns []string, dataMap []base.DataMap) bool {
	colLen := len(columns)
	isOk := true
	for i, item := range dataMap {
		if item.SrcColIndex < 0 {
			continue
		}
		if item.SrcColIndex >= colLen {
			isOk = false
			dataMap[i].SrcColIndex = -1
			dataMap[i].SrcColName = ""
		} else if item.SrcColName != columns[item.SrcColIndex] {
			isOk = false
		}
	}
	return isOk
}
func DataImportRouter(c echo.Context) error {
	var dataImport base.DataImport
	jsonStr := c.FormValue("dataImport")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &dataImport)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	} else {
		return echo.NewHTTPError(http.StatusBadRequest, "FormValue：dataImport不能为空！")
	}
	fileName := dataImport.FilePath
	path, err := base.WorkDir()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	dataImport.FilePath = path + "/upload_file/" + dataImport.FilePath
	err = dataImport.InitReader()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	ignoreErrStr := c.FormValue("ignoreErr")
	if ignoreErrStr == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "FormValue：ignoreErr不能为空！")
	}
	ignoreErr, err := strconv.ParseBool(ignoreErrStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	var errorDatas []base.ErrorData
	jsonStr = c.FormValue("errorDatas")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &errorDatas)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	var dataMap []base.DataMap
	jsonStr = c.FormValue("dataMaps")
	if jsonStr != "" {
		err := json.Unmarshal([]byte(jsonStr), &dataMap)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		isNewStr := c.FormValue("isNewMap")
		isNew := false
		if isNewStr != "" {
			isNew, err = strconv.ParseBool(isNewStr)
			if err != nil {
				return echo.NewHTTPError(http.StatusBadRequest, "isNew参数错误："+err.Error())
			}
		}
		if len(dataMap) > 0 {
			err = dataImport.SetDataMap(dataMap, isNew)
			if err != nil {
				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
			}
		}
	}
	go dataImport.Import(fileName, ignoreErr, errorDatas)
	return c.JSON(http.StatusOK, "ok")
}
func DataImportProcessRouter(c echo.Context) error {
	fileName := c.FormValue("fileName")
	if fileName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "FormValue：fileName不能为空！")
	}
	redis := base.RedisClient
	key := "ip:" + fileName
	infoMap, err := redis.HGetAll(key).Result()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	errorDatas := infoMap["errorDatas"]
	if errorDatas == "" {
		errorDatas = "[]"
	}
	retVal := fmt.Sprintf(`{"success":"%s","finish":"%s","successCount":"%s","errorDatas":%s,"percent":"%s","msg":"%s","err":"%s"}`,
		infoMap["success"], infoMap["finish"], infoMap["dataLen"], errorDatas, infoMap["percent"], infoMap["msg"], infoMap["err"])
	return c.HTML(http.StatusOK, retVal)
}
func getIpAttr(r *http.Request) string {
	ip := r.Header.Get("Remote_addr")
	if ip == "" {
		ip = r.RemoteAddr
	}
	ip = strings.Replace(ip, "[::1]", "127.0.0.0", 1)
	return ip
}
func getSuccessMessage(fileName string, sheetNames []string, dataMap string) string {
	var buff bytes.Buffer
	buff.WriteString(`{"success":true,"dataMap":`)
	buff.WriteString(dataMap)
	buff.WriteString(`,"fileName":"`)
	buff.WriteString(fileName)
	buff.WriteString(`","sheetNames":[`)
	l := len(sheetNames)
	for i, sName := range sheetNames {
		buff.WriteRune('"')
		buff.WriteString(sName)
		buff.WriteRune('"')
		if i < l-1 {
			buff.WriteRune(',')
		}
	}
	buff.WriteString(`]}`)
	return buff.String()
}
func getErrorMessage(message string) string {
	var buff bytes.Buffer
	buff.WriteString(`{"success":false,"message":"`)
	buff.WriteString(message)
	buff.WriteString(`"}`)
	return buff.String()
}
